package com.thti.mecool.client.service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

/**
 * 
 * @author weiguo.ren
 * 
 */

public class JsonUtil {
	/**
	 * JSON转object
	 * 
	 * @param object
	 * @param jsonString
	 * @return
	 */
	public static Object jsonToObject(Class<?> cla, String jsonString) {
		/**
		 * 得到 属性 列表
		 */
		Object object = null;
		try {
			
			object = cla.newInstance();
			if (object == null) {
				return null;
			}
			/**
			 * 得到 方法 列表
			 */
			Method[] ms = cla.getMethods();

			Field[] fields = cla.getDeclaredFields();

			JSONObject jsonObject = new JSONObject(jsonString);
			for (int i = 0; i < fields.length; i++) {
				String fieldName = fields[i].getName().substring(0, 1).toUpperCase()+ fields[i].getName().substring(1);
				
				String methodName = "set"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1);
				
			
				Method method = null;
				/**
				 * 查找 写入 属性的方法
				 */
				for (int j = 0; j < ms.length; j++) {

					if (ms[j].getName().equalsIgnoreCase(methodName)) {
						
						method = ms[j];
						continue;
					}
				}
				String pName = fields[i].getName();
				Iterator<?> iterator = jsonObject.keys();
				while (iterator.hasNext()) {
					String jName = (String) iterator.next();
					if (pName.equalsIgnoreCase(jName)) {
						
						Object value = jsonObject.get(jName);
						

						if (null == value
								|| value.toString().equalsIgnoreCase("null")) {
						} else {
							String typeName = fields[i].getType()
									.getSimpleName();
							
							Class<?> fieldClazz = fields[i].getType();
						

							if (fieldClazz.isAssignableFrom(List.class)) {
								Type fc = fields[i].getGenericType();
								if (fc == null)
									continue;
								Class<?> genericClazz = null;
								if (fc instanceof ParameterizedType) // 如果是泛型参数的类型
								{
									ParameterizedType pt = (ParameterizedType) fc;
									genericClazz = (Class<?>) pt
											.getActualTypeArguments()[0]; // 得到泛型里的class类型对象�?
								}
								Object o=null;
								if(jsonObject.getJSONArray(jName).isNull(0)){
									method.invoke(object, o);
								}else{
								  o = jsonToArray(genericClazz,
										jsonObject.getJSONArray(jName));
								 method.invoke(object, o);
								}
							} else if ("String".equals(typeName)) {
								method.invoke(object, value.toString());
							} else if ("int".equals(typeName)
									|| "Integer".equals(typeName)) {
								
								if(value.toString().equals("") || value.toString()==null){
									 method.invoke(object,0);
									}else
									{
										method.invoke(object,
												Integer.parseInt(value.toString()));
									}
							} else if ("float".equals(typeName)
									|| "Float".equals(typeName)) {
								method.invoke(object,
										Float.parseFloat(value.toString()));
							} else if ("double".equals(typeName)
									|| "Double".equals(typeName)) {
								method.invoke(object,
										Double.parseDouble(value.toString()));
							} else if ("boolean".equals(typeName)
									|| "Boolean".equals(typeName)) {
								method.invoke(object,
										Boolean.parseBoolean(value.toString()));
							} else if ("long".equals(typeName)
									|| "Long".equals(typeName)) {
								method.invoke(object,
										Long.parseLong(value.toString()));
							} else {
								Object o = jsonToObject(fields[i].getType(), value.toString());
								method.invoke(object, o);
							}
						}
					}
				}
			  
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return object;
	}

	public static Object jsonToArray(Class<?> cla, JSONArray jsonArray) {
		
		List list=new  ArrayList();
	
		/**
		 * 得到 属性 列表
		 */
		  for(int i=0;i<jsonArray.length();i++){ 
              JSONObject jsonObject2 = (JSONObject)jsonArray.opt(i);
            
              Object object = null;
          	
    		try {
    			object = cla.newInstance();
    			if (object == null) {
    				return null;
    			}
    			/**
    			 * 得到 方法 列表
    			 */
    			Method[] ms = cla.getMethods();

    			Field[] fields = cla.getDeclaredFields();
    			 
		            for (int j = 0; j < fields.length; j++) {
		            	Field	 fieldMethod = fields[j];
						String fieldName=fieldMethod.getName().substring(0, 1).toUpperCase()+fieldMethod.getName().substring(1); 
						String methodName = "set"
							+ fieldName.substring(0, 1).toUpperCase()
							+ fieldName.substring(1);
						Iterator<?> iterator = jsonObject2.keys();
						 while(iterator.hasNext()){
							 String jName = (String) iterator.next();
								if (fieldName.equalsIgnoreCase(jName)){
									Object value = jsonObject2.get(jName);
								
									Method method =cla.getMethod(methodName, new Class[]{fieldMethod.getType()});
									String getName="get"
										+ fieldName.substring(0, 1).toUpperCase()
										+ fieldName.substring(1);
									Method getMethod=cla.getMethod(getName, new Class[]{});   
								
									
									if (null == value
											|| value.toString().equalsIgnoreCase("null")) {
									} else {
										String typeName = fieldMethod.getType()
												.getSimpleName();
									
										Class<?> fieldClazz = fieldMethod.getType();
										
										
										if (fieldClazz.isAssignableFrom(List.class)) {
											Type fc = fieldMethod.getGenericType();
											if (fc == null)
												continue;
											Class<?> genericClazz = null;
											if (fc instanceof ParameterizedType) // 如果是泛型参数的类型
											{
												ParameterizedType pt = (ParameterizedType) fc;
												genericClazz = (Class<?>) pt
														.getActualTypeArguments()[0]; // 得到泛型里的class类型对象�?
											}
											Object o=null;
											if(jsonObject2.getJSONArray(jName).isNull(0)){
												method.invoke(object, o);
											}else{
												 o = jsonToArray(genericClazz,
														jsonObject2.getJSONArray(jName));
												method.invoke(object, o);
											}
										}else 
										
										if ("String".equals(typeName)) {
											
											method.invoke(object, value.toString());
										} else if ("int".equals(typeName)
												|| "Integer".equals(typeName)) {
											if(value.toString().equals("") || value.toString()==null){
											 method.invoke(object,0);
											}else
											{
												method.invoke(object,
														Integer.parseInt(value.toString()));
											}
										} else if ("float".equals(typeName)
												|| "Float".equals(typeName)) {
											method.invoke(object,
													Float.parseFloat(value.toString()));
										} else if ("double".equals(typeName)
												|| "Double".equals(typeName)) {
											method.invoke(object,
													Double.parseDouble(value.toString()));
										} else if ("boolean".equals(typeName)
												|| "Boolean".equals(typeName)) {
											method.invoke(object,
													Boolean.parseBoolean(value.toString()));
										} else if ("long".equals(typeName)
												|| "Long".equals(typeName)) {
											method.invoke(object,
													Long.parseLong(value.toString()));
										} else {
										
											Object o = jsonToObject(fieldMethod.getType(), value.toString());
											method.invoke(object, o);
										}
									}

								} 
							 
						 }
						
					}
		} catch (Exception e) {
			e.printStackTrace();
		}
		list.add(object);
	  }
		return list;
	}

	/**
	 * Object转Json
	 * 
	 * @param object
	 * @return
	 */
	public static String objectToJson(Object object) {
		StringBuffer sBuffer = new StringBuffer();
		Field[] fields = object.getClass().getDeclaredFields();
		Method[] ms = object.getClass().getMethods();
		if (fields != null && fields.length > 0) {
			sBuffer.append("{");
			for (int i = 0; i < fields.length; i++) {

				String fieldName = fields[i].getName();

				String methodName = "get"
						+ fieldName.substring(0, 1).toUpperCase()
						+ fieldName.substring(1);

				Method method = null;

				/**
				 * 查找 读取 属性的方法
				 */
				for (int j = 0; j < ms.length; j++) {
					if (ms[j].getName().equals(methodName)) {
						method = ms[j];
						continue;
					}
				}

				if (method == null) {
					methodName = "is" + fieldName.substring(0, 1).toUpperCase()
							+ fieldName.substring(1);
					/**
					 * 查找 读取 属性的方法
					 */
					for (int j = 0; j < ms.length; j++) {
						if (ms[j].getName().equals(methodName)) {
							method = ms[j];
							continue;
						}
					}

				}
				if (method != null) {
					sBuffer.append("\"" + fields[i].getName() + "\":");
					try {
						try {
							String simpleName = method.invoke(object)
									.getClass().getSimpleName();
							if ("String".equalsIgnoreCase(simpleName)
									|| "Integer".equalsIgnoreCase(simpleName)
									|| "int".equalsIgnoreCase(simpleName)
									|| "Float".equalsIgnoreCase(simpleName)
									|| "Double".equalsIgnoreCase(simpleName)
									|| "Boolean".equalsIgnoreCase(simpleName)
									|| "Long".equalsIgnoreCase(simpleName)) {
								sBuffer.append("\"" + method.invoke(object)
										+ "\"");
							} else {
								String json = objectToJson(method
										.invoke(object));
								sBuffer.append(json);
							}
						} catch (InvocationTargetException e) {
							e.printStackTrace();
						}
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
					if (i != fields.length - 1) {
						sBuffer.append(",");
					}
				}

			}
			sBuffer.append("}");
		}
		return sBuffer.toString();
	}

}
